﻿using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.XPath;
using Office = Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;
using Tools = Microsoft.Office.Tools;
using System.Diagnostics;
using eRechnung_3_0.Properties;
using ebDoc = eRechnung_3_0.Globals;

namespace eRechnung_3_0
{
    class InvoiceXML
    {
        #region xPath DEfinitionen
        public const string Prefix = "xmlns:eb='http://www.ebinterface.at/schema/3p0/'";
        public const string PrefixURLeb = "http://www.ebinterface.at/schema/3p0/";
        public const string PrefixURLsig = "http://www.w3.org/2000/09/xmldsig#";
        public const string xPathListLine = "eb:Invoice/eb:Details/eb:ItemList/eb:ListLineItem";
        public const string xPathItemList = "eb:Invoice/eb:Details/eb:ItemList";
        public const string xPathPos = "eb:PositionNumber";
        public const string xPathDesc = "eb:Description";
        public const string xPathArtikelNr = "eb:BillersArticleNumber";
        public const string xPathUnit = "eb:Quantity/@eb:Unit";
        public const string xPathQuantity = "eb:Quantity";
        public const string xPathUnitPrice = "eb:UnitPrice";
        public const string xPathReductionRate = "eb:ReductionRate";
        public const string xPathAmount = "eb:LineItemAmount";
        public const string xPathTaxRate = "eb:TaxRate";

        public const string xPathInvoice = "eb:Invoice";
        public const string xPathBillerName = "//eb:Biller/eb:Address/eb:Name";
        public const string xPathBillerStreet = "//eb:Biller/eb:Address/eb:Street";
        public const string xPathBillerTown = "//eb:Biller/eb:Address/eb:Town";
        public const string xPathBillerZip = "//eb:Biller/eb:Address/eb:ZIP";
        public const string xPathBillerCountry = "//eb:Biller/eb:Address/eb:Country";
        public const string xPathBillerContact = "//eb:Biller/eb:Address/eb:Contact";
        public const string xPathBillerPhone = "//eb:Biller/eb:Address/eb:Phone";
        public const string xPathBillerEmail = "//eb:Biller/eb:Address/eb:Email";
        public const string xPathBillerVATID = "//eb:Biller/eb:VATIdentificationNumber";

        public const string xPathInvRecName = "//eb:InvoiceRecipient/eb:Address/eb:Name";
        public const string xPathInvRecSalute = "//eb:InvoiceRecipient/eb:Address/eb:Salutation";
        public const string xPathInvRecStreet = "//eb:InvoiceRecipient/eb:Address/eb:Street";
        public const string xPathInvRecTown = "//eb:InvoiceRecipient/eb:Address/eb:Town";
        public const string xPathInvRecZip = "//eb:InvoiceRecipient/eb:Address/eb:ZIP";
        public const string xPathInvRecCountry = "//eb:InvoiceRecipient/eb:Address/eb:Country";
        public const string xPathInvRecPhone = "//eb:InvoiceRecipient/eb:Address/eb:Phone";
        public const string xPathInvRecContact = "//eb:InvoiceRecipient/eb:Address/eb:Contact";
        public const string xPathInvRecEmail = "//eb:InvoiceRecipient/eb:Address/eb:Email";
        public const string xPathInvRecVATID = "//eb:InvoiceRecipient/eb:VATIdentificationNumber";
        public const string xPathInvRecBillerID = "//eb:InvoiceRecipient/eb:BillersInvoiceRecipientID";

        public const string xPathDocumentType = "//eb:Invoice/@eb:DocumentType";
        public const string xPathDocumentTitle = "//eb:Invoice/@eb:DocumentTitle";
        public const string xPathCurrency = "//eb:Invoice/@eb:InvoiceCurrency";
        public const string xPathGeneratingSystem = "//eb:Invoice/@eb:GeneratingSystem";

        public const string xPathInvNumber = "//eb:InvoiceNumber";
        public const string xPathInvDate = "//eb:InvoiceDate";
        public const string xPathDeliveryDate = "//eb:Delivery/eb:Date";
        public const string xPathOrderRefID = "//eb:OrderReference/eb:OrderID";
        public const string xPathOrderRefDate = "//eb:OrderReference/eb:ReferenceDate";
        public const string xPathOrderReference = "//eb:OrderReference";

        public const string xPathPaymtDuedate = "//eb:PaymentConditions/eb:DueDate";
        public const string xPathBankName = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankName";
        public const string xPathBankBLZ = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankCode";
        public const string xPathBankLand = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankCode/@eb:BankCodeType";
        public const string xPathBankAcctNr = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankAccountNr";
        public const string xPathBankAcctOwner = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankAccountOwner";
        public const string xPathBankIBAN = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:IBAN";
        public const string xPathPaymtMethode = "//eb:PaymentMethod";

        public const string xPathSignature = "//dsig:Signature";

        public const string xPathDiscntPmntCond = "eb:Invoice/eb:PaymentConditions";
        public const string xPathDiscntLine = "eb:Invoice/eb:PaymentConditions/eb:Discount";
        public const string xPathDiscntProz = "eb:Percentage";
        public const string xPathDiscntDate = "eb:PaymentDate";
        public const string DueDateXML = "<eb:DueDate>{0}</eb:DueDate>";
        public const string DiscItemXML = "<eb:Discount>" +
                                          "<eb:PaymentDate>{0}</eb:PaymentDate>" +
                                          "<eb:Percentage>{1}</eb:Percentage>" +
                                          "<eb:Amount>{2}</eb:Amount>" +
                                          "</eb:Discount>";


        public const string xPathTaxVATList = "//eb:Tax/eb:VAT";

        public const string xPathTotGrossAmount = "//eb:TotalGrossAmount";

        private const string VatItemXML = "<eb:Item>" +
                "<eb:TaxedAmount>{0}</eb:TaxedAmount>" +
                "<eb:TaxRate>{1}</eb:TaxRate>" +
                "<eb:Amount>{2}</eb:Amount>" +
                "</eb:Item>";

        private const string DetailItemXml = "<eb:ListLineItem>" +
            "<eb:PositionNumber>{0}</eb:PositionNumber>" +
            "<eb:Description>{1}</eb:Description>" +
            "<eb:BillersArticleNumber>{2}</eb:BillersArticleNumber>" +
            "<eb:Quantity eb:Unit='{3}'>{4}</eb:Quantity>" +
            "<eb:UnitPrice>{5}</eb:UnitPrice>" +
            "<eb:TaxRate>{6}</eb:TaxRate>" +
            "<eb:DiscountFlag>{7}</eb:DiscountFlag>" +
            "<eb:ReductionRate>{8}</eb:ReductionRate>" +
            "<eb:LineItemAmount>{9}</eb:LineItemAmount>" +
            "</eb:ListLineItem>";

        private string DocumentTitle = "XML Vorlage für ebInterface 3.0 Word Formular";

        #endregion

        private object missing = Type.Missing;

        public string InvCurrency;
        public string InvBillerCountry;
        public string InvRecipientCountry;
        public string InvBankCountry;
        public string InvDocType;
        public string InvDocTitle;

        public DsInvoice InvDetails;

        public InvoiceXML()
        {
            InvDetails = new DsInvoice();
        }

        public string GetFromXMLResource()
        {
            Assembly Asm = Assembly.GetExecutingAssembly();
            //            Stream St = Asm.GetManifestResourceStream("eRechnung_3_0.DEMORechnungMESONIC.XML");
            Stream St = Asm.GetManifestResourceStream("eRechnung_3_0.ebInterface30_Leer.xml");
            StreamReader ResRd = new StreamReader(St);
            if (ResRd != null)
            {
                string xmlData = ResRd.ReadToEnd();
                return (xmlData);
            }

            return (null);
        }

        public Office.CustomXMLPart AddCustomXmlPart(string xmlData)
        {
            // Office.CustomXMLPart InvoiceXMLPart;
            if (xmlData != null)
            {
                ebDoc.ThisDocument.InvoiceXMLPart = ebDoc.ThisDocument.CustomXMLParts.SelectByID(ebDoc.ThisDocument.InvoiceXMLPartID);
                if (ebDoc.ThisDocument.InvoiceXMLPartID != null)
                {
                    ebDoc.ThisDocument.InvoiceXMLPart = ebDoc.ThisDocument.CustomXMLParts.Add(xmlData, missing);
                    ebDoc.ThisDocument.InvoiceXMLPartID = ebDoc.ThisDocument.InvoiceXMLPart.Id;
                }
                ebDoc.ThisDocument.InvoiceXMLPart.NamespaceManager.AddNamespace("eb", InvoiceXML.PrefixURLeb);
                return (ebDoc.ThisDocument.InvoiceXMLPart);
            }
            return (null);
        }

        public static void RemoveEmptyNodes(XmlDocument doc, XmlNamespaceManager xNmgr)
        {

        }

        /// <summary>
        /// 
        /// Speicher den angegebene CustomXMLPart als XML Datei
        /// </summary>
        /// <param name="XMLPart">Der zu speichernde CustomXMLPart</param>
        public void SaveXML(Office.CustomXMLPart XMLPart, bool AlsVorlage)
        {
            if (AlsVorlage!=true)
            {
                string CC_Verify = VerifyAllCC();
                if (CC_Verify != "")
                {
                    ebDoc.ThisDocument.SetFehlerText(CC_Verify);
                    DialogResult dResult = MessageBox.Show("Fehler im Dokument.\r\n" +
                        "Details finden Sie auf Seite 2 dieses Formulars.\r\n" +
                                     "XML trotzdem speichern?", "ebInterface XML speichern", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);

                    if (dResult == DialogResult.Cancel)
                    {
                        return;
                    }
                }

            }
            
            XmlDocument xdoc = new XmlDocument();
            XmlNamespaceManager xNMgr = new XmlNamespaceManager(xdoc.NameTable);
            XmlNode xn;
            xNMgr.AddNamespace("eb", PrefixURLeb);
            xNMgr.AddNamespace("dsig", PrefixURLsig);
            try
            {
                string ItemXML = string.Empty;
                xdoc.LoadXml(XMLPart.XML);
                xdoc.CreateXmlDeclaration("1.0", "utf-8", string.Empty);

                xn = xdoc.SelectSingleNode(xPathBillerCountry, xNMgr);
                xn.InnerText = InvBillerCountry;
                xn = xdoc.SelectSingleNode(xPathSignature, xNMgr);
                if (xn!=null)
                {
                    Debug.WriteLine("gelöscht: " + xn.InnerXml);
                    xn.ParentNode.RemoveChild(xn);
                }

                xdoc.SelectSingleNode(xPathBankLand, xNMgr).InnerText = InvBankCountry;
                xdoc.SelectSingleNode(xPathCurrency, xNMgr).InnerText = InvCurrency;
                xdoc.SelectSingleNode(xPathInvRecCountry, xNMgr).InnerText = InvRecipientCountry;
                xdoc.SelectSingleNode(xPathDocumentType, xNMgr).InnerText = InvDocType;
                xdoc.SelectSingleNode(xPathDocumentTitle, xNMgr).InnerText = InvDocTitle;
                string[] tempSVN = ebDoc.ThisDocument.GetSVNInfo().Split(';');
                if (AlsVorlage!=true)
                {
                    DocumentTitle = ebDoc.ThisDocument.GetAsmTitle();
                }
                xdoc.SelectSingleNode(xPathGeneratingSystem, xNMgr).InnerText = DocumentTitle+" "+tempSVN[0];
                xdoc.SelectSingleNode(xPathInvDate, xNMgr).InnerText = FormatDateVonXML(xdoc.SelectSingleNode(xPathInvDate, xNMgr).InnerText);
                xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr).InnerText = FormatDateVonXML(xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr).InnerText);
                xdoc.SelectSingleNode(xPathOrderRefDate, xNMgr).InnerText = FormatDateVonXML(xdoc.SelectSingleNode(xPathOrderRefDate, xNMgr).InnerText);
                xdoc.SelectSingleNode(xPathTotGrossAmount, xNMgr).InnerText = FormatDecimal(ebDoc.ThisDocument.BetragInklMwSt);
                ItemXML = Details2XML();
                XmlNode ItemNode = xdoc.SelectSingleNode(xPathItemList, xNMgr);
                ItemNode.InnerXml = ItemXML;

                ItemXML = MwSt2XML();
                ItemNode = xdoc.SelectSingleNode(xPathTaxVATList, xNMgr);
                ItemNode.InnerXml = ItemXML;

                ItemXML = Skonto2XML();
                ItemNode = xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr);
                ItemXML = string.Format(DueDateXML, ItemNode.InnerXml) + ItemXML;
                ItemNode = xdoc.SelectSingleNode(xPathDiscntPmntCond, xNMgr);
                ItemNode.InnerXml = ItemXML;

                // Kein Löschen von leeren Nodes bei speichern als XML Vorlage
                if (AlsVorlage!=true)
                {
                    //XPathNavigator xpathNavigator = xdoc.CreateNavigator();
                    //string select = "//*";
                    //XPathNodeIterator xpathIterator = xpathNavigator.Select(select, xNMgr);
                    //while (xpathIterator.MoveNext())
                    //{
                    //    Debug.WriteLine(string.Format("Found element: {0}.", xpathIterator.Current.Name));
                    //    if (xpathIterator.Current.Value == "")
                    //    {
                    //        Debug.WriteLine("Delete");
                    //        xpathIterator.Current.DeleteSelf();
                    //    }
                    //} 
                    Word.Document wDoc = ebDoc.ThisDocument.Application.ActiveDocument;
                    string wCCNode = string.Empty;
                    foreach (Word.ContentControl wCC in wDoc.ContentControls)
                    {
                        wCCNode = wCC.XMLMapping.XPath;
                        Debug.WriteLine(wCC.PlaceholderText.Value+";"+wCCNode+";<"+wCC.Tag+">");
                        
                        if ((wCCNode!=null)&&(wCC.Tag==null))    // optionale Node
                        {
                            xn = xdoc.SelectSingleNode(wCCNode, xNMgr);
                            if (xn.InnerText=="")
                            {
                                xn.ParentNode.RemoveChild(xn);

                            }
                        }
                    }
                    // Test ob xPathOrderReference xPathPaymtMethode leer sind
                    xn = xdoc.SelectSingleNode(xPathOrderReference, xNMgr);
                    if ((xn != null) && ((xn.InnerXml == "")||(xn.InnerText=="")))
                    {
                        xn.ParentNode.RemoveChild(xn);
                    }

                    xn = xdoc.SelectSingleNode(xPathPaymtMethode, xNMgr);
                    if ((xn != null) && (xn.InnerText == ""))
                    {
                        xn.ParentNode.RemoveChild(xn);
                    }

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei XML Verarbeitung.\r\n" + ex.Message);
                return;
            }
            if (AlsVorlage!=true)       // wenn als Vorlage zu speichern, keine Validierung
            {
                string Tmp2Filename = System.IO.Path.GetTempFileName();  // Temporaeren Dateinamen wählen
                xdoc.Save(Tmp2Filename);

                bool isValid = IsEbInterfaceXMLValid(xdoc, Tmp2Filename, false);
                if (isValid == false)
                {
                    DialogResult dResult = MessageBox.Show("Fehler bei der XML Validierung.\r\n" +
                        "Details finden Sie auf Seite 2 dieses Formulars und \r\nin der ebInterface Dokumentation\r\n"+
                                     "XML trotzdem speichern?", "ebInterface XML speichern", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);

                    if (dResult == DialogResult.Cancel)
                    {
                        return;
                    }
                }
                
            }
            string XMLFile = string.Empty;
            // StreamWriter XMLWriter;
            SaveFileDialog sDlg = new SaveFileDialog();
            sDlg.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
            sDlg.FilterIndex = 1;
            sDlg.RestoreDirectory = true;

            try
            {
                if (sDlg.ShowDialog() == DialogResult.OK)
                {
                    if (File.Exists(sDlg.FileName))
                    {
                        File.Delete(sDlg.FileName);
                    }
                    XmlWriterSettings xwsetting = new XmlWriterSettings();
                    xwsetting.Indent = true;
                    xwsetting.NewLineChars = Environment.NewLine;
                    XmlWriter myXMLWriter = XmlTextWriter.Create(sDlg.FileName, xwsetting);
                    xdoc.Save(myXMLWriter);
                    myXMLWriter.Close();
                    myXMLWriter.Flush();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Save As XML");
            }
        }


        public string LoadXMLTemplate()
        {
            string XMLFile = string.Empty;
            // StreamWriter XMLWriter;
            OpenFileDialog sDlg = new OpenFileDialog();
            sDlg.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
            sDlg.FilterIndex = 1;
            sDlg.RestoreDirectory = true;

            try
            {
                if (sDlg.ShowDialog() == DialogResult.OK)
                {
                    XMLFile = sDlg.FileName;
                    StreamReader ResRd = new StreamReader(XMLFile);
                    if (ResRd != null)
                    {
                        string xmlData = ResRd.ReadToEnd();
                        ResRd.Close();
//                        bool isValid = IsEbInterfaceXMLValid(xdoc);
                        XmlDocument xdoc = new XmlDocument();
                        xdoc.LoadXml(xmlData);
                        XmlNamespaceManager xNMgr = new XmlNamespaceManager(xdoc.NameTable);
                        xNMgr.AddNamespace("eb", PrefixURLeb);
                        xNMgr.AddNamespace("dsig", PrefixURLsig);
                        // bool isValid = IsEbInterfaceXMLValid(xdoc,sDlg.FileName,false);
                        XmlNode xGenSys = xdoc.SelectSingleNode(xPathGeneratingSystem, xNMgr);

                        bool isValid = false;
                        if (xGenSys.InnerText.Length >= DocumentTitle.Length)
                        {
                            if (xGenSys.InnerText.Substring(0, DocumentTitle.Length) == DocumentTitle)
                            {
                                isValid = true;
                            }
                        }
                        if (isValid==false)
                        {
                            // ebDoc.ThisDocument.SetFehlerText(""); // XML nicht geladen.
                            MessageBox.Show("Die XML Vorlage wurde nicht mit ebInterface 3.0 Word Formular Vorlage erstellt. Die Vorlage wurde nicht geladen",
                                "XML Vorlage laden", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return (string.Empty); // XML Daten sind nicht gültig
                        }
                        return (xmlData);
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler beim Lesen der XML Vorlage "+XMLFile+"\n"+ex.Message,"Lesen XML Vorlage",MessageBoxButtons.OK,MessageBoxIcon.Error);
            }
            return string.Empty;
        }


        #region Hilfefunktionen

        private string GetNameFromXMLError(string errorTxt)
        {
            string[] temp = errorTxt.Split('\t');
            return temp[0];
        }

        private string AppendRetVal(string oldval, string addval)
        {
            string retVal;
            if (oldval == "")
            {
                retVal = addval;
            }
            else
            {
                retVal = oldval+"\n" + addval;
            }
            return retVal;
        }

        private string VerifyAllCC()
        {
            Word.Document wDoc = ebDoc.ThisDocument.Application.ActiveDocument;
            string retVal = string.Empty;
            foreach (Word.ContentControl wCC in wDoc.ContentControls)
            {
                Debug.WriteLine(wCC.PlaceholderText.Value + "/" + wCC.Tag + "<" + wCC.Range.Text);
                switch (wCC.Tag)
                {
                    case "Nicht Leer":
                        if (wCC.ShowingPlaceholderText == true)
                        {
                            retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Darf nicht leer sein.");
                        }
                        break;
                    case "VAT":
                        if (ebDoc.ThisDocument.BetragInklMwSt>=10000)
                        {
                            if ((wCC.ShowingPlaceholderText==true)||(wCC.Range.Text=="00000000"))
                            {
                                retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Empfänger VAT-ID fehlt bei Rechnungsbetrag>10000.");
                            }
                        }
                        break;
                    case "Numerisch":
                        if (wCC.ShowingPlaceholderText != true)
                        {
                            try
                            {
                                decimal decVal = decimal.Parse(wCC.Range.Text);
                            }
                            catch (Exception)
                            {
                                retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Ist nicht numerisch.");
                            }
                        }
                        else 
                        {
                            retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Darf nicht leer sein.");
                        }
                        break;
                    default:
                        break;
                }
            }
            return retVal;
        }

        private Word.ContentControl FindCCfromXMLMapping(string name)
        {
            Word.Document wDoc = ebDoc.ThisDocument.Application.ActiveDocument;
            foreach (Word.ContentControl wCC in wDoc.ContentControls)
            {
                
                if (wCC.XMLMapping.XPath == name)
                {
                    return wCC;
                }
            }
            return null;
        }
        private string GetPlaceholderText4Error(string eText)
        {
            string wCCName;
            Word.ContentControl wCCTemp;
            wCCName = GetNameFromXMLError(eText);
            if (wCCName == "")
            {
                return ("?Name unbekannt?");
            }
            wCCTemp = FindCCfromXMLMapping(wCCName);
            if (wCCTemp==null)
            {
                return ("?XMLMapping unbekannt?");
            }
            return (wCCTemp.PlaceholderText.Value);

        }


        private XmlSchemaSet GetXmlSchemas()
        {
            XmlSchemaSet xSchema = new XmlSchemaSet();
            try
            {
                Assembly Asm = Assembly.GetExecutingAssembly();
                using (System.Xml.XmlReader rdr = System.Xml.XmlReader.Create(Asm.GetManifestResourceStream("eRechnung_3_0.W3C-XMLDSig.xsd")))
                {
                  xSchema.Add("http://www.w3.org/2000/09/xmldsig#", rdr);
                }
                using (System.Xml.XmlReader rdr = System.Xml.XmlReader.Create(Asm.GetManifestResourceStream("eRechnung_3_0.Invoice.xsd")))
                {
                    xSchema.Add("http://www.ebinterface.at/schema/3p0/", rdr);
                }
                return xSchema;

            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei Add Schema\r\n" + ex.Message);

            }
            return null;
        }

        private bool IsEbInterfaceXMLValid(XmlDocument xdoc, string filename, bool isDoc)
        {
            XmlValidator xmlChecker = new XmlValidator();
            XmlValidator.XmlValidatorResult result;
            ebDoc.ThisDocument.SetFehlerText(""); // Fehlerliste löschen
            string errorTxt = string.Empty;
            string temp = string.Empty;
            try
            {
                xmlChecker.SchemaSet = GetXmlSchemas();

                if (isDoc==true)
                {
                    result = xmlChecker.ValidateXmlDocument(xdoc, ValidationType.Schema, null);
                    
                }
                else
                {
                    result = xmlChecker.ValidateXmlFile(filename, ValidationType.Schema, null);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei XML Validierung von '" + xdoc + "'.\r\n" +
                                ex.Message + "\r\n",
                "XML Validieren", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            

            switch (result)
            {
                case XmlValidator.XmlValidatorResult.Valid:
                    return true;
                    break;
                case XmlValidator.XmlValidatorResult.ErrorsExists:
                    errorTxt = "Fehler im XML Dokument '"+xdoc+"'.\r\n";
                    for (int i = 0; i < xmlChecker.Errors.Count; i++)
                    {
                        temp = xmlChecker.Errors[i].ToString();
                        temp = GetPlaceholderText4Error(temp) + "\t" + temp;
                        errorTxt = errorTxt+"\r\n" + temp;
                    }
                    if (xmlChecker.Warnings.Count > 0)
                    {
                        errorTxt = errorTxt + "\r\nWarnungen im XML Dokument '" + xdoc + "'.\r\n";
                        for (int i = 0; i < xmlChecker.Warnings.Count; i++)
                        {
                            temp = xmlChecker.Warnings[i].ToString();
                            temp = GetPlaceholderText4Error(temp) + "\t" + temp;
                            errorTxt = errorTxt + "\r\n" + temp;
                        }
                    }

                    Debug.WriteLine(errorTxt);
                    // MessageBox.Show(errorTxt);
                    ebDoc.ThisDocument.SetFehlerText(errorTxt);
                    return false;
                    break;
                case XmlValidator.XmlValidatorResult.WarningsExists:
                    errorTxt = "Warnungen im XML Dokument '" + xdoc + "'.\r\n";
                    for (int i = 0; i < xmlChecker.Warnings.Count; i++)
                    {
                        temp = xmlChecker.Warnings[i].ToString();
                        temp = GetPlaceholderText4Error(temp) + "\t" + temp;
                        errorTxt = errorTxt + "\r\n" + temp;
                    }
                    Debug.WriteLine(errorTxt);
                    // MessageBox.Show(errorTxt);
                    ebDoc.ThisDocument.SetFehlerText(errorTxt);
                    return true;
                    break;
                default:
                    break;
            }
            return false;
        }
        public string GetNodeValue(Office.CustomXMLPart XMLPart, string xPathList, string XMLFieldName, int i)
        {
            string XMLField = string.Empty;
            string value = string.Empty;
            XMLField = string.Format(xPathList + "[{0}]", i + 1) + "/" + XMLFieldName;
            Office.CustomXMLNode xn = XMLPart.SelectSingleNode(XMLField);
            value = xn.Text;
            return (value);
        }

        private string FormatDecimal(decimal val)
        {
            string retval = val.ToString("#0.00", System.Globalization.CultureInfo.InvariantCulture);
            return (retval);
        }
        private string FormatDateVonXML(string datum)
        {
            if (datum=="")
            {
                return datum;
            }
            try
            {
                string rdat = FormatDate(DateTime.Parse(datum));
                return rdat;
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        private string FormatDate(DateTime datum)
        {
            string retval = datum.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
            return retval;
        }

        private decimal ConvertXML2Decimal(string wert)
        {
            if (wert == "")
            {
                return (0);
            }
            string wert2 = wert.Replace(".", ",");
            decimal dec = decimal.Parse(wert2);
            return (dec);

        #endregion
        }
        /// <summary>
        /// Erzeugt aus der Detail Tabelle die XML Ausgabe
        /// </summary>
        /// <returns></returns>
        public string Details2XML()
        {
            string position;        // 0
            string Beschreibung;    // 1
            string ArtikelNr;       // 2
            string Einheit;         // 3
            string Menge;           // 4
            string stueckpreis;     // 5
            string mwst;            // 6
            string RabattFlag;      // 7
            string Rabatt;          // 8
            string gesamtbetrag;    // 9


            string NodeValue = string.Empty;

            try
            {
                DataRow[] rows = InvDetails.TblInvDetails.Select();
                int i = 1;
                foreach (DsInvoice.TblInvDetailsRow dsRow in rows)
                {
                    ArtikelNr = dsRow.SpArtikelNr;
                    Menge = FormatDecimal(dsRow.SpMenge);
                    Beschreibung = dsRow.SpBezeichnung;
                    stueckpreis = FormatDecimal(dsRow.SpEinzelpreis);
                    Einheit = dsRow.SpEinheit;
                    position = (i++).ToString();
                    gesamtbetrag = FormatDecimal(dsRow.SpGesamtBetrag);
                    mwst = FormatDecimal(dsRow.SpMwSt);
                    Rabatt = FormatDecimal(dsRow.SpRabattProz);
                    RabattFlag = "false";
                    if (dsRow.SpRabattProz != 0)
                    {
                        RabattFlag = "true";
                    }

                    NodeValue = NodeValue + string.Format(DetailItemXml,
                                position,        // 0
                                Beschreibung,    // 1
                                ArtikelNr,       // 2
                                Einheit,         // 3
                                Menge,           // 4
                                stueckpreis,     // 5
                                mwst,            // 6
                                RabattFlag,      // 7
                                Rabatt,          // 8
                                gesamtbetrag    // 9
                                );
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei Erstellen der XML für Detailzeilen" + ex.Message, "XML Erstellen", MessageBoxButtons.OK, MessageBoxIcon.Error);
                throw;
            }

            return (NodeValue);
        }

        public string MwSt2XML()
        {
            string NodeValue = string.Empty;

            try
            {
                DataRow[] dsRows = InvDetails.TblMwStSummen.Select();
                foreach (DsInvoice.TblMwStSummenRow row in dsRows)
                {
                    NodeValue = NodeValue + string.Format(VatItemXML,
                        FormatDecimal(row.spBasisBetrag),
                        FormatDecimal(row.spMwSt),
                        FormatDecimal(row.spMwStBetrag));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei Erstellen XML für MwST." + ex.Message, "XML Erstellen", MessageBoxButtons.OK, MessageBoxIcon.Error);
                throw;
            }
            return (NodeValue);
        }

        public string Skonto2XML()
        {
            string NodeValue = string.Empty;

            try
            {
                DataRow[] dsRows = InvDetails.TblInvSkonto.Select();
                foreach (DsInvoice.TblInvSkontoRow row in dsRows)
                {
                    NodeValue = NodeValue + string.Format(DiscItemXML,
                        FormatDate(row.SpBisDatum),
                        FormatDecimal(row.SpSkontoProz),
                        FormatDecimal(row.spSkontoBetrag));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei Erstellen XML für Skonto." + ex.Message, "XML Erstellen", MessageBoxButtons.OK, MessageBoxIcon.Error);
                throw;
            }
            return (NodeValue);
        }
        public void LoadSkontoTable(Office.CustomXMLPart XMLPart, DsInvoice myDs)
        {
            decimal SktoPrz;
            DateTime SktoDate;
            DsInvoice.TblInvSkontoRow myRow;
            string ReDatum = ebDoc.ThisDocument.GetInvoiceDate();
            if (ReDatum != "")
            {
                try
                {
                    ebDoc.ThisDocument.Rechnungsdatum = DateTime.Parse(ReDatum);
                }
                catch (Exception ex)
                {
                    ebDoc.ThisDocument.Rechnungsdatum = DateTime.Today;
                }
            }


            try
            {
                myDs.TblInvSkonto.Clear();
                int icnt = XMLPart.SelectNodes(xPathDiscntLine).Count;
                for (int i = 0; i < icnt; i++)
                {
                    string StrSktoPrz = GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntProz, i);
                    if (StrSktoPrz != "")
                    {
                        SktoPrz = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntProz, i));
                        SktoDate = DateTime.Parse(GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntDate, i));
                        myRow = (DsInvoice.TblInvSkontoRow)myDs.TblInvSkonto.Rows.Add(new object[] { SktoPrz, SktoDate, 0, 0, 0 });
                        myDs.TblInvSkonto.UpdateSkontoTage(myRow);
                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


        }

        public bool LoadDetailsTable(Office.CustomXMLPart XMLPart, DsInvoice myDs)
        {
            decimal Menge;
            decimal RabattProz;
            string ArtikelNr;
            string Beschreibung;
            decimal stueckpreis;
            string Einheit;
            decimal Mwst;

            try
            {
                myDs.TblInvDetails.Clear();
                int icnt = XMLPart.SelectNodes(xPathListLine).Count;

                // DsDetails myDS = new DsDetails();


                for (int i = 0; i < icnt; i++)
                {
                    string StrMenge = GetNodeValue(XMLPart, xPathListLine, xPathQuantity, i);
                    if (StrMenge != "")
                    {
                        Menge = ConvertXML2Decimal(StrMenge);
                        RabattProz = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathReductionRate, i));
                        ArtikelNr = GetNodeValue(XMLPart, xPathListLine, xPathArtikelNr, i);
                        Beschreibung = GetNodeValue(XMLPart, xPathListLine, xPathDesc, i);
                        stueckpreis = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathUnitPrice, i));
                        Mwst = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathTaxRate, i));
                        if (ebDoc.ThisDocument.IsMwStInSettings(Mwst)==false)
                        {
                            throw (new Exception("Der MwSt Satz "+Mwst.ToString("0.00")+" in der XML Vorlage ist nicht in den aktuellen Einstellungen eingetragen.\n"+
                                "Ergänzen Sie die MwSt Tabelle in den Einstellungen um diesen Wert und laden Sie dann die XML Vorlage erneut."));
                        }
                        Einheit = GetNodeValue(XMLPart, xPathListLine, xPathUnit, i);
                        DsInvoice.TblInvDetailsRow myRow = (DsInvoice.TblInvDetailsRow)myDs.TblInvDetails.Rows.Add();
                        myRow.SpMenge = Menge;
                        myRow.SpArtikelNr = ArtikelNr;
                        myRow.SpBezeichnung = Beschreibung;
                        myRow.SpEinzelpreis = stueckpreis;
                        myRow.SpEinheit = Einheit;
                        myRow.SpRabattProz = RabattProz;
                        myRow.SpMwSt = Mwst;
                    }                
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }

            return true;
        }

    }
}
